下記コードを改造し, circle要素のfill属性,stroke-width属性についても,配列dataの値を利用して描画するようにしてください.
ref. https://www.w3.org/TR/SVG/shapes.html#CircleElement
/* onloadで呼び出される関数 */
function init(){
var width = 800;
var height = 600;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// データにstroke属性を追加する
var data = [{x: 10, y:20, r:10, stroke: "#FF0000"},{x: 100, y:50, r:70, stroke: "#0000FF"},{x: 30, y:90, r:10, stroke: "#FF00FF"}];
// データを描画する
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx",function(d){return d.x;})
.attr("cy",function(d){return d.y;})
.attr("r", function(d){return d.r;})
.attr("fill","yellow")
// 変更点
.attr("stroke",function(d){return d.stroke;})
.attr("stroke-width",10);
};
表示結果:
描画に用いたデータを表形式で示します.中心座標(x,y),半径(r), 線色(stroke)を定義しています.線色はカラーコード(RGB値を16進数で表現;#RRGGBB)を用いています.
変数dataへの値の追加とattr関数の変更を実施しています.
/* onloadで呼び出される関数 */
function init(){
var width = 800;
var height = 600;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// データにfill,strokewidth属性を追加する
var data = [
{x: 10, y: 20, r: 10, fill: "#00FF00", stroke: "#FF0000", strokewidth: 2},
{x: 100, y: 50, r: 70, fill: "#FF0000", stroke: "#0000FF", strokewidth: 10},
{x: 30, y: 90, r: 10, fill: "#00FFFF", stroke: "#FF00FF", strokewidth: 5}
];
// データを描画する
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx",function(d){return d.x;})
.attr("cy",function(d){return d.y;})
.attr("r", function(d){return d.r;})
// fill属性を設定
.attr("fill",function(d){return d.fill;})
.attr("stroke",function(d){return d.stroke;})
// stroke属性を設定
.attr("stroke-width",function(d){return d.strokewidth;});
};
表示結果:
描画に用いたデータを表形式で示します. 背景色が付いている行が新たに追加されたデータとなります.
上記課題に加え,circle要素をrect要素に変更したものを提出してください.
ref. https://www.w3.org/TR/SVG/shapes.html#RectElement
rect 要素には circl e要素にあった cx, cy, r は定義されていません. 変わりに x, y, width, height が定義されています.定義にあわせてプログラムを編集します.
/* onloadで呼び出される関数 */
function init(){
var width = 800;
var height = 600;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
var data = [
{x: 10, y: 20, width: 10, height: 20, fill: "#00FF00", stroke: "#FF0000", strokewidth: 2},
{x: 100, y: 50, width: 70, height: 10, fill: "#FF0000", stroke: "#0000FF", strokewidth: 10},
{x: 30, y: 90, width: 10, height: 5, fill: "#00FFFF", stroke: "#FF00FF", strokewidth: 5}
];
// データを描画する
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x",function(d){return d.x;})
.attr("y",function(d){return d.y;})
.attr("width", function(d){return d.width;})
.attr("height", function(d){return d.height;})
.attr("fill",function(d){return d.fill;})
.attr("stroke",function(d){return d.stroke;})
.attr("stroke-width",function(d){return d.strokewidth;});
};
表示結果:
描画に用いたデータを表形式で示します. 新たに追加したデータを背景色で色分けしています.
本日は d3.js を用いた本格的な可視化に取り組みます. 具体的にはアメリカ地質調査所(United States Geological Survey; USGS) Earthquake Hazards Program(https://earthquake.usgs.gov/earthquakes/)が公開する地震観測データを読み込み,地図上にマッピングします.
まず,SVGの描画領域について説明します. SVGはスクリーン座標系を採用しており,画面左上が原点(0,0)となります.
x座標およびy座標の最大値はSVG要素のwidth属性およびheight属性に設定された値となります.
それでは描画領域いっぱいに四角形を描画してみましょう. script.js を以下のように書き換えてください.(単にSVG要素の縦横幅をrect要素の縦横幅に設定しているだけです)
function init(){
// SVG要素の作成
var width = 800;
var height = 600;
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// データ初期化
var data = [
{x: 0, y:0, w:width, h: height,fill: "#00FF00",stroke: "#FF0000",stroke_width: 10}
];
// 初期化したデータからrect要素を生成
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x",function(d){return d.x;})
.attr("y",function(d){return d.y;})
.attr("width", function(d){return d.w;})
.attr("height", function(d){return d.h;})
.attr("fill",function(d){return d.fill;})
.attr("stroke",function(d){return d.stroke;})
.attr("stroke-width",function(d){return d.stroke_width});
};
デベロッパーツールで確認すると, rect要素のwidth,height属性に値が設定されていることがわかります.
それでは,この描画領域をウェブブラウザいっぱいに広げるにはどのようにしたらよいでしょうか. このような場合は,ウェブブラウザの描画領域(ビューポート)の縦横幅をSVG要素に設定します
ウェブブラウザのビューポート領域を得るには, window.innerWidth,window.innerHeightプロパティを使います.
それでは先程のスクリプトの下記箇所を
var width = 800;
var height = 600;
以下のように変更してください.
var width = window.innerWidth;
var height = window.innerHeight;
変更後,ウェブブラウザをリロードしてください. ビューポートいっぱいに四角形が描画されます.
今度はデータを動的に生成します.スクリプトを下記のように書き換えてください.
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// データを生成する
var data = [];
for( var i = 0; i < 100; i++ ) {
data.push({x: Math.random()*width, y: Math.random()*height});
}
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx",function(d){return d.x;})
.attr("cy",function(d){return d.y;})
.attr("r", 5)
.attr("fill","blue")
.attr("stroke","white")
.attr("stroke-width",4);
};
実行結果は次のとおりです.
ここではランダムに100個の円描画用のデータを作成し,それを描画しています.
データ生成しているのは下記箇所となります.
// データを生成する
var data = [];
for( var i = 0; i < 100; i++ ) {
data.push({x: Math.random()*width, y: Math.random()*height});
}
「var data = []」で変数を初期化し,続くfor文で100個のデータを作成しています. for文の書式は以下のとおりです.
for(初期値;条件式;更新式){
繰返し処理
}
上記のコードでは初期値は「var i = 0」,条件式は「i < 100」,更新式は「i++」です.++ はインクリメント演算子と呼ばれ変数に+1します.つまり「i++」は「i = i + 1」と等価です.
このfor文により変数iが100となるまで処理を繰り返すことになります. for文の理解のために,条件式を「i<10」と変更してみてください. 円はいくつ描画されるでしょうか?
なお,円の中心座標は乱数で求めています.具体的にはスクリプトにある「Math.random()*width」や「Math.random()*height」が担当しています.Math.random()は0以上1未満の擬似乱数を返す関数です.そのため,計算の結果,値の範囲は0〜widthやheight以下となります.
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random
for文の詳しい解説は以下のサイトを参照してください.
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Loops_and_iteration#for_statement
d3.jsはCSVファイルの読み込みにも対応しています.
ここでは,USGS Earthquake Hazard ProgramのSpreadsheet Format(http://earthquake.usgs.gov/earthquakes/feed/v1.0/csv.php)のページにある一日に発生した全ての地震を記録したCSVファイルを利用します.
http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv
script.jsを以下のように変更してください.
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// CSVを読み込む
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url,function(data){
console.log(data);
});
};
スクリプトを保存し,ブラウザをリロードすると, CSVデータが取得されコンソール上に地震発生箇所が表示されます.
CSVデータでが地震の発生場所を経度・緯度で記録していますが, スクリーン座標系であるSVG上ではその緯度・経度が示す値を使って描画することはできません. 一旦,緯度・経度座標(緯度,経度)をスクリーン座標(X,Y)に変換する必要があります.
つまり,緯度(latitude)の範囲[-90.0, 90.0]をスクリーン座標の範囲[height,0]に変換します.
http://earthquake.usgs.gov/earthquakes/feed/v1.0/glossary.php#latitude
経度(longitude)の範囲は[-180.0, 180.0]なのでスクリーン座標の範囲[0,width]に変換します.
http://earthquake.usgs.gov/earthquakes/feed/v1.0/glossary.php#longitude
このような変換処理を正規化と呼びます.d3.jsではd3.scaleを使って実現します.
https://github.com/d3/d3/blob/master/API.md#scales-d3-scale
それでは,d3.scaleを早速試してみましょう.script.jsを以下のように変更してください.
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// 経度を幅の範囲に正規化する関数を定義
var xScale = d3.scale.linear().domain([-180,180]).range([0,width]);
// 緯度を高さの範囲に正規化する関数を定義
var yScale = d3.scale.linear().domain([-90,90]).range([height,0]);
// CSVを読み込む
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url,function(data){
console.log(data);
// データ毎に処理を行う
data.forEach(function(d,i){
console.log("longitude:"+i+":"+d.longitude+","+xScale(d.longitude));
console.log("latitude:"+i+":"+d.latitude + ","+yScale(d.latitude));
});
});
};
ブラウザをリロードし,デベロッパーツールのコンソールを開いてください.
緯度・経度座標がスクリーン座標に変換されて出力されているはずです. これで地震発生地を可視化する準備が整いました.
それでは先程のコードを更に変更してみましょう.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// 経度を幅の範囲に正規化
var xScale = d3.scale.linear().domain([-180,180]).range([0,width]);
// 緯度を高さの範囲に正規化
var yScale = d3.scale.linear().domain([-90,90]).range([height,0]);
// CSVを読み込む
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url,function(data){
svg.selectAll("circle").data(data).enter()
.append("circle")
// xScale関数でd.longitudeをスクリーン座標に変換する
.attr("cx",function(d){return xScale(d.longitude);})
// yScale関数でd.latitudeをスクリーン座標に変換する
.attr("cy",function(d){return yScale(d.latitude);})
.attr("r",1);
});
};
ブラウザをリロードすると,地震の発生箇所がきちんと描画されているはずです.
地震の発生箇所だけでは可視化としては面白くないので, 地震の深度を可視化してみましょう.深度は塗り色で表現しみます.
d3.jsを用いて数値と色をマッピングする場合は「interpolate(d3.interpolateRgb).range(最小の色,最大の色)」を使うと便利です.
スクリプトを以下のように変更してください.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// 経度を幅の範囲に正規化
var xScale = d3.scale.linear().domain([-180,180]).range([0,width]);
// 緯度を高さの範囲に正規化
var yScale = d3.scale.linear().domain([-90,90]).range([height,0]);
// 深度を色の範囲(#b2cbe4〜#001e43)に正規化
var depth = d3.scale.linear()
.domain([0,1000])
.interpolate(d3.interpolateRgb)
.range(['#b2cbe4', '#001e43'])
// CSVを読み込む
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url,function(data){
svg.selectAll("circle").data(data).enter()
.append("circle")
// xScale関数でd.longitudeをスクリーン座標に変換する
.attr("cx",function(d){return xScale(d.longitude);})
// yScale関数でd.latitudeをスクリーン座標に変換する
.attr("cy",function(d){return yScale(d.latitude);})
.attr("r",10)
.attr("fill",function(d){return depth(d.depth);});
});
};
CSVデータ上の深度の定義は以下のとおりです.
http://earthquake.usgs.gov/data/comcat/data-eventterms.php#depth
可視化結果例は以下のとおりです.
ようやくそれらしくなってきました.
さて,深度の正規化には定義されている固定値を利用しましたが, 場合によってはデータ内部の最大・最小値を利用して正規化することもあります.
このような場合は,d3.maxおよびd3.minを使います.
たとえば,マグニチュードの最大・最小値を取得するには以下のようにコーディングします.
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// 経度を幅の範囲に正規化
var xScale = d3.scale.linear().domain([-180,180]).range([0,width]);
// 緯度を高さの範囲に正規化
var yScale = d3.scale.linear().domain([-90,90]).range([height,0]);
// CSVを読み込む
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url,function(data){
// マグニチュードの最小値を取得する
var min = d3.min(data,function(d){return d.mag;});
// マグニチュードの最大値を取得する
var max = d3.max(data,function(d){return d.mag;});
// コンソールに表示する
console.log("min:"+min);
console.log("max:"+max);
});
};
いかがでしょうか.コンソールにマグニチュードの最小値と最大値が表示されていることと思います.
それではいままでの知識を総動員して地震発生地を可視化してみましょう. 深度の可視化 を改造し,深度の範囲をd3.max,d3.minで取得し,正規化に利用します.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// 経度を幅の範囲に正規化
var xScale = d3.scale.linear().domain([-180,180]).range([0,width]);
// 緯度を高さの範囲に正規化
var yScale = d3.scale.linear().domain([-90,90]).range([height,0]);
// CSVを読み込む
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url,function(data){
// 深度の最小値と最大値を取得
var min = d3.min(data,function(a){return a.depth;});
var max = d3.max(data,function(b){return b.depth;});
// 深度の最小値と最大値を色の範囲(#b2cbe4〜#001e43)にマッピング(正規化)
var depth = d3.scale.linear().domain([min,max]).interpolate(d3.interpolateRgb).range(['#b2cbe4', '#001e43'])
svg.selectAll("circle").data(data).enter()
.append("circle")
// xScale関数でd.longitudeをスクリーン座標に変換する
.attr("cx",function(d){return xScale(d.longitude);})
// yScale関数でd.latitudeをスクリーン座標に変換する
.attr("cy",function(d){return yScale(d.latitude);})
.attr("r",10)
.attr("fill",function(d){return depth(d.depth);});
});
};
つぎに地図の描画手法を学びます.本演習では比較的手軽に利用できるleaflet(http://leafletjs.com/)ライブラリを使います.
リファレンスは以下からアクセスできます.
http://leafletjs.com/reference.html
まず,leafletライブラリを読み込みます.
index.html を以下のように変更し, leafletライブラリを読み込みます.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ひな形HTMLファイル</title>
<!-- d3.jsライブラリの読み込み -->
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<!-- leaflet -->
<!--
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
-->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v1.0.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet/v1.0.2/leaflet.js"></script>
<!-- スタイルシート -->
<link rel="stylesheet" href="style.css" type="text/css" />
<!-- 処理用スクリプト -->
<script type="text/javascript" src="script.js" ></script>
</head>
<body onload="init();">
<div id="screen"></div>
</body>
</html>
つぎにscript.jsを以下のように変更します.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// map描画領域の設定
d3.select("#screen").attr("id","map").attr("style", "width: "+width+"px; height: "+height+"px;");
// mapの作成
var map = L.map('map').setView([35.70089,139.4300], 2);
// クレジット文字列
var credit = '<a href="http://portal.cyberjapan.jp/help/termsofuse.html">国土地理院</a>';
// 国土地理院のタイル
var tileurl = 'http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png';
//タイルの設定
L.tileLayer(tileurl, {minZoom: 2, maxZoom: 18, attribution: credit,}).addTo(map);
};
ブラウザをリロードしてください.
インタラクティブな地図が表示されたと思います.
地図の描画には国土地理院のタイルを使用しています.以下を参照してくさい.
http://maps.gsi.go.jp/development/ichiran.html
タイルを変更する場合はzoom levelの指定に注意が必要です.
たとえば、国土地理院のenglishタイルを用いる場合は、利用可能なズームレベルが5〜11となります.
http://maps.gsi.go.jp/development/ichiran.html#english
こういった場合はminZoom, maxZoomを変更し,ズーム範囲を固定します.また,初期ズームレベルも合わせて変更します.
script.jsを以下のように変更してください.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// map描画領域の設定
d3.select("#screen").attr("id","map").attr("style", "width: "+width+"px; height: "+height+"px;");
// mapの作成
var map = L.map('map').setView([35.70089,139.4300], 5);
// クレジット文字列
var credit = '<a href="http://portal.cyberjapan.jp/help/termsofuse.html">国土地理院</a>';
// 国土地理院のタイル
var tileurl = 'http://cyberjapandata.gsi.go.jp/xyz/english/{z}/{x}/{y}.png';
//タイルの設定
L.tileLayer(tileurl, {minZoom: 5,maxZoom: 11, attribution: credit,}).addTo(map);
};
表示結果は次のようになります.
タイルには国土地理院だけでなく, OpenStreetMapのタイルも使用できます.OpenStreetMapのタイルを使う場合は以下のようにします.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// svg要素を作成する
var svg = d3.select("#screen").append("svg")
.attr("id","svg")
.attr("width",width)
.attr("height",height);
// map描画領域の設定
d3.select("#screen").attr("id","map").attr("style", "width: "+width+"px; height: "+height+"px;");
// mapの作成
var map = L.map('map').setView([35.70089,139.4300], 5);
// クレジット文字列
var credit = '<a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
// 国土地理院のタイル
var tileurl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
//タイルの設定
L.tileLayer(tileurl, {minZoom: 2,maxZoom: 18, attribution: credit,}).addTo(map);
};
つぎにleafletで描画した地図に散布図を描画します.
基本的にはSVG要素を追加すればよいのですが, leaflet上の地図に描画する場合,少しばかり特殊な処理, 具体的には地図のズームレベルに合わせて緯度経度座標を変更する必要があります.
以下がその変換処理を加えたコードとなります.
/* onloadで呼び出される関数 */
function init(){
var width = window.innerWidth;
var height = window.innerHeight;
// map描画領域の設定
d3.select("#screen").attr("id","map").attr("style", "width: "+width+"px; height: "+height+"px;");
// mapの作成
var map = L.map('map').setView([35.70089,139.4300], 2);
// クレジット文字列
var credit = '<a href="http://portal.cyberjapan.jp/help/termsofuse.html">国土地理院</a>';
// 国土地理院のタイル
var tileurl = 'http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png';
//タイルの設定
L.tileLayer(tileurl, {maxZoom: 18, attribution: credit,}).addTo(map);
// svgレイヤの初期化
// leflet v0.7.7以下の場合は以下
// map._initPathRoot();
// leflet v0.8以降
var layer = L.svg().addTo(map);
// 地図上のsvgレイヤにg要素を作る
var g = d3.select("#map").select("svg").append("g");
var url = "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv"
d3.csv(url, function(error,data) {
var max = d3.max(data,function(a){return a.depth;});
var min = d3.min(data,function(b){return b.depth;});
var depth = d3.scale.linear().domain([min,max]).interpolate(d3.interpolateRgb).range(['#b2cbe4', '#001e43'])
// csvファイルの緯度経度からLatLngオブジェクトを作成
data.forEach(function(d){
d.LatLngObj = new L.LatLng(d.latitude, d.longitude);
});
// g要素に円を描画する
var circle = g.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx",0)
.attr("cy",0)
.attr("r",10)
.attr("stroke","#0000ff")
.attr("stroke-width",2)
.attr("fill",function(d){return depth(d.depth);});
// 再描画用の関数を設定
// leflet v0.7.7以下の場合は以下
//map.on("viewreset", update);
// leflet v0.8以降
layer.on("update",update);
update();
// 再描画用関数
function update() {
// データの緯度経度を地図座標に変換
circle.attr("cx", function(d) {
var point = map.latLngToLayerPoint(d.LatLngObj);
return point.x;
})
.attr("cy", function(d) {
var point = map.latLngToLayerPoint(d.LatLngObj);
return point.y;
});
}
});
};
transform属性を用いるとupdate関数の中身を以下のように書き換えることができます.
// 再描画用関数
function update() {
// データの緯度経度を地図座標に変換
circle.attr("transform", function(d) {
var point = map.latLngToLayerPoint(d.LatLngObj);
return "translate("+ point.x+","+ point.y+")";
});
}
transform属性には様々な変換を記述することが可能です.下記サイトを参考にしてください.
https://developer.mozilla.org/ja/docs/Web/SVG/Attribute/transform
translate関数の例:
<svg width=800 height=600>
<circle cx="0" cy="0" r="10" fill="red" stroke="blue" stroke-width="2" transform="translate(100,100)"/>
</svg>
地震発生地の可視化2 を改造し,深度の色範囲を変更してください.
可視化例:
地震発生地の可視化2 を改造し,円の半径をマグニチュードで表現するようにしてください.
http://earthquake.usgs.gov/data/comcat/data-eventterms.php#mag
可視化例: